#ifndef ITERATION_METHODS_H
#define ITERATION_METHODS_H

#include <stdint.h>

#include "../../utils/MatrixUtils.h"

namespace NumericalAnalysis
{
    enum Method
    {
    	Method_Jacobi,
    	Method_GaussSeidel
    };

    // Iteration method:
    // The parameters are:
    // Iteration method to use (Jacobi or GaussSeidel)
    // Matrix dimensions n
    // File path to read the matrix A (nxn).
    // File path to read the matrix b (nx1).
    // File path to read the matrix x (nx1).
    // Error tolerance
    // Max number of iterations
    // Also we need to pass three output parameters for:
    // Last iteration
    // First order norm value
    // Last iteration x matrix.
    void IterationMethod(const Method method, const uint32_t matrixDimension, const std::string& filePathForA, 
    	const std::string& filePathForb, const std::string& filePathForx, const double errorTolerance, 
    	const uint32_t maxIterations, uint32_t& outLastIteration, double& outFirstOrderNorm, Utils::Matriz& outMatrix);


    // Jacobi method:
    // The parameters are:
    // Matrix dimensions n
    // File path to read the matrix A (nxn).
    // File path to read the matrix b (nx1).
    // File path to read the matrix x (nx1).
    // Error tolerance
    // Max number of iterations
    // Also we need to pass three output parameters for:
    // Last iteration
    // First order norm value
    // Last iteration x matrix.
    void JacobiMethod(const uint32_t matrixDimension, const std::string& filePathForA, const std::string& filePathForb, 
    	const std::string& filePathForx, const double errorTolerance, const uint32_t maxIterations, uint32_t& outLastIteration, 
    	double& outFirstOrderNorm, Utils::Matriz& outMatrix);


    // Gauss-Seidel method:
    // The parameters are:
    // Matrix dimensions n
    // File path to read the matrix A (nxn).
    // File path to read the matrix b (nx1).
    // File path to read the matrix x (nx1).
    // Error tolerance
    // Max number of iterations
    // Also we need to pass three output parameters for:
    // Last iteration
    // First order norm value
    // Last iteration x matrix.
    void GaussSeidelMethod(const uint32_t matrixDimension, const std::string& filePathForA, const std::string& filePathForb, 
    	const std::string& filePathForx, const double errorTolerance, const uint32_t maxIterations, uint32_t& outLastIteration, 
    	double& outFirstOrderNorm, Utils::Matriz& outMatrix);
}

#endif // ITERATION_METHODS_H
